<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\ZZMed\ZHospMember;
use App\Models\ZPituitaryAnswer;
use App\Models\ZPituitaryComplete;
use App\Models\ZPituitaryUser;
use App\Models\ZPituitaryUserType;
use App\Models\ZPituitaryUserVisitLevel;
use App\Models\ZPituitaryVisitRecords;
use App\Models\ZZMed\ZUser;
use App\Services\VisitRemindService;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

/**
 *  病历就诊管理
 * Class VisitController
 * @package App\Http\Controllers\Api
 */
class VisitController extends Controller
{

    /**
     *  查看医院患者访视列表
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
     */
    public function getPatientList(Request $request)
    {
        $data = $request->all();
        if (!isset($data['hosp_id']) || !isset($data['dept_id'])) {
            return $this->error(-11001, '参数缺少医院或科室id');
        }
        $data = array_filter($data, 'strlen');
        $hospId = $data['hosp_id'];
        $deptId = $data['dept_id'];
        $recordSort = isset($data['record_sort']) && $data['record_sort'] ? $data['record_sort'] : "desc";

        // 是否涉及用户搜索
        $userSearchStatus = false;
        $userQuery = ZUser::query()->from('z_user as u')
            ->selectRaw('id as user_id');
        // code 姓名-编号-手机号 三合一搜索
        if (isset($data['code']) && $data['code']) {
            $userSearchStatus = true;
            $code = $data['code'];
            $userQuery->where(function ($query) use ($code) {
                $query->where('u.barcode', $code)
                    ->orWhere('u.name', $code)
                    ->orWhere('u.cell', $code);
            });
        }
        // sex  性别
        if (isset($data['sex'])) {
            $userSearchStatus = true;
            $userQuery->where('u.sex', $data['sex']);
        }
        // age_from 年龄
        if (isset($data['age_from']) && $data['age_from']) {
            $userSearchStatus = true;
            $age_from = date("Y-12-31", strtotime('-' . $data['age_from'] . ' years'));
            $userQuery->where('u.bday', '<=', $age_from);
        }
        // age_to 年龄
        if (isset($data['age_to']) && $data['age_to']) {
            $userSearchStatus = true;
            $age_to = date("Y-01-01", strtotime('-' . $data['age_to'] . ' years'));
            $userQuery->where('u.bday', '>=', $age_to);
        }

        $searchUserIds = [];
        if ($userSearchStatus) {
            $userSearchArr = $userQuery->orderByDesc('id')->get()->toArray();
            $searchUserIds = array_column($userSearchArr, 'user_id');
            $searchUserIds = $searchUserIds ? $searchUserIds : [1];
        }


        $visits = ZPituitaryVisitRecords::query()
            ->from('z_pituitary_visit_records as r')
            ->select(DB::raw("r.id,r.user_id,v.visit_level, gp.created_at,r3.visit_at"))
            ->join(DB::raw(" (SELECT r1.id,r1.visit_at FROM ( SELECT * FROM z_pituitary_visit_records WHERE  type = 0 and hosp_id =$hospId and dept_id =$deptId  ORDER BY visit_at desc) as r1 group by r1.user_id order by r1.visit_at $recordSort) as r3 "), 'r3.id', '=', 'r.id')
            ->leftJoin('z_pituitary_visit_level as v', 'v.id', '=', 'r.visit_id')
            ->join('z_pituitary_user as gp', 'r.user_id', '=', 'gp.user_id')
            ->when($searchUserIds, function ($query) use ($searchUserIds) {
                return $query->whereIn('r.user_id', $searchUserIds);
            });

        // 入组时间
        if (isset($data['created_from']) && $data['created_from']) {
            $visits->where('gp.created_at', '>=', $data['created_from']);
        }
        // 入组时间
        if (isset($data['created_to']) && $data['created_to']) {
            $visits->where('gp.created_at', '<=', Carbon::parse($data['created_to'])->endOfDay());
        }

        $visits->where('r.visit_id', '!=', 0)
            ->where('r.type', 0);
        if (isset($data['record_sort'])) {
            $visits->orderBy('r.visit_at', $data['record_sort']);
        }
        if (isset($data['join_sort'])) {
            $visits->orderBy('gp.created_at', $data['join_sort']);
        }

        // 默认分页大小
        $pageSize = $data['page_size'] ?? 10;
        $result = $visits->orderByDesc('r.id')
            ->paginate($pageSize, ['*'], 'page_no');

        $result = convertsArray($result);
        $data = convertsArray($result['data']);

        $resultUserIds = collect($data)->pluck('user_id')->toArray();
        if ($resultUserIds) {
            //这里过滤 如果获取的V和实际V不一致
            $maxVisitLevelArr = ZPituitaryUserVisitLevel::query()
                ->select(DB::raw('max(visit_level) as visit_level'), 'user_id')
                ->whereIn('user_id', $resultUserIds)
                ->groupBy("user_id")->get()->toArray();

            // 最大访视
            $maxVisitLevelArr = array_column($maxVisitLevelArr, 'visit_level', 'user_id');

            // 处理用户基本信息  == 跨库 需要单独查询用户数据
            $userBaseInfoArr = ZUser::query()->selectRaw('id as user_id,name,sex,bday,barcode,cell')
                ->whereIn('id', $resultUserIds)
                ->get()->toArray();
            $baseInfoArr = [];
            foreach ($userBaseInfoArr as $one) {
                $baseInfoArr[$one['user_id']] = $one;
            }
            // 完成度
            $completeArr = ZPituitaryComplete::query()->where('visit_level', 1)
                ->where('category_id',100)
                ->whereIn('user_id', $resultUserIds)->get()->toArray();
            $userCompleteArr = array_column($completeArr, 'complete_b','user_id');

            // 处理用户诊断标签
            $userCtTagIds = [];
            $userCtTagNames = [];
            $tagRes = ZPituitaryUserType::query()->whereIn('user_id', $resultUserIds)->get()->toArray();

            foreach ($tagRes as $item) {
                $userCtTagIds[$item['user_id']][] = $item['type'];
                $userCtTagNames[$item['user_id']][] = ZPituitaryUserType::PITUITARY_TYPE[$item['type']] ?? '';
            }

            // 干预手段
            $gyRes = ZPituitaryAnswer::query()
                ->selectRaw('user_id,answer_id,answer_name')
                ->where('visit_level', 1)
                ->whereIn('user_id', $resultUserIds)
                ->where('subquestion_id', 153)->get()->toArray();

            $gyData = [];
            foreach ($gyRes as $item) {
                $gyData[$item['user_id']][] = $item['answer_name'];
            }

            // 手术日期
            $suRes = ZPituitaryAnswer::query()
                ->selectRaw('user_id,answer_id,answer_name')
                ->where('visit_level', 1)
                ->whereIn('user_id', $resultUserIds)
                ->where('answer_id', 15501)->get()->toArray();
            $suData = [];
            foreach ($suRes as $item) {
                $suData[$item['user_id']] = $item['answer_name'];
            }

            foreach ($data as &$item) {
                // 补充基本信息
                $item['name'] = $baseInfoArr[$item['user_id']]['name'] ?? '';
                $item['sex'] = $baseInfoArr[$item['user_id']]['sex'] ?? '';
                $item['bday'] = $baseInfoArr[$item['user_id']]['bday'] ?? '';
                $item['bar_code'] = $baseInfoArr[$item['user_id']]['barcode'] ?? '';
                $item['barcode'] = $baseInfoArr[$item['user_id']]['barcode'] ?? '';
                $item['cell'] = $baseInfoArr[$item['user_id']]['cell'] ?? '';

                $item['visit_level'] = $maxVisitLevelArr[$item['user_id']] ?? 0;
                $item['age'] = getBday($item['bday']) ?? '-';
                $item['created_at'] = date('Y-m-d', strtotime($item['created_at']));
                // 完成度
                $item['complete_per'] = $userCompleteArr[$item['user_id']] ?? 0;
                // 垂体类型标签
                $item['ct_type_ids'] = $userCtTagIds[$item['user_id']] ?? '';
                $item['ct_type_names'] = $userCtTagNames[$item['user_id']] ?? '';
                // 首次干预手段
                $item['gy_names'] = $gyData[$item['user_id']] ?? '';
                // 手术日期
                $item['su_date'] = $suData[$item['user_id']] ?? '';

            }
        }
        $result['data'] = $data;
        return $this->success($result);
    }


    /**
     *  获取访视记录历史
     * @param Request $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
     */
    public function getVisitLevelHistory(Request $request)
    {

        $params = $request->all();
        $userId = $params['user_id'] ?? 0;
        $pageNo = $params['page_no'] ?? 1;

        $visits = ZPituitaryUserVisitLevel::query()
            ->where('user_id', $userId)
            ->orderBy('visit_level', 'asc')
            ->get(['id', 'visit_level', 'visit_at'])->toArray();

        $total = collect($visits)->count();
        $data = array_values(collect($visits)->forPage($pageNo, 10)->toArray());

        foreach ($data as $k => $item) {
            $data[$k]['complete_per'] = 80;
        }

        $firstAt = ZPituitaryUser::query()->where('user_id', $userId)->first()->created_at ?? '';
        if (!$firstAt) {
            return $this->error(40005, "用户未登记入组,请登记后创建访视!");
        }
        $maxVisit = ZPituitaryUserVisitLevel::getMaxVisitInfo($userId);
        $nextLevel = $maxVisit['visit_level'] + 1;
        $nextVisits = VisitRemindService::levelToVisitData($firstAt, $nextLevel);

        foreach ($data as $k => $item) {
            $visits = VisitRemindService::levelToVisitData($firstAt, $item['visit_level']);
            $data[$k]['visit_period_date'] = $visits["visit_period_date"];
        }
        $result = [
            'total' => $total,
            'data' => $data,
            'nex_visit_level' => $nextLevel,
            'next_visit_at' => $nextVisits['visit_period_date']
        ];

        return $this->success($result);

    }

    /**
     *  保存或创建访视
     * @param Request $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
     * @throws \App\Exceptions\AuthException
     */
    public function createVisitLevel(Request $request)
    {

        $user = $this->authUser();
        $params = $request->all();
        $visitDate = $params['visit_at'] ?? Carbon::now()->format('Y-m-d');

        $userId = $params['user_id'] ?? 0;

        $visitLevel = ZPituitaryUserVisitLevel::getVisitLevel($userId, $visitDate);

        if (!$visitLevel) {
            return $this->error(40005, "用户未登记入组,请登记后创建访视!");
        }

        $visitInfo = ZPituitaryUserVisitLevel::query()->where([
            'user_id' => $userId,
            'visit_level' => $visitLevel,
        ])->first();
        if (!$visitInfo) {
            ZPituitaryUserVisitLevel::query()->create([
                'user_id' => $userId,
                'visit_level' => $visitLevel,
                'visit_at' => $visitDate,
                'hosp_id' => $user->hosp_id,
                'dept_id' => ZHospMember::getDocDeptId($user->id),
                'doc_id' => $user->id
            ]);
        }

        return $this->success([]);


    }


    /**
     *  保存或创建就诊
     * @param Request $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
     * @throws \App\Exceptions\AuthException
     */
    public function createVisitRecord(Request $request)
    {
        $data = $request->all();
        $required = [
            'user_id' => 'required',
            'hosp_id' => 'required',
            'dept_id' => 'required',
            'visit_level' => 'required',
        ];

        $validate = Validator::make($data, $required);
        if ($validate->fails()) {
            return $this->error(422, json_encode($validate->errors()));
        }


        list ($userId, $visitLevel, $hospId, $deptId) = [$data['user_id'], $data['visit_level'], $data['hosp_id'], $data['dept_id']];

        $visitDate = date('Y-m-d', time());
        $visitTime = date('Y-m-d H:i:s', time());
        $docId = $this->authUser()->id;

        $visitLevel = ZPituitaryUserVisitLevel::getVisitLevel($userId, $visitDate);

        if (!$visitLevel) {
            return $this->error(40005, "用户未登记入组,请登记后创建访视!");
        }

        // check 访视是否存在，没有的话创建
        $visit = ZPituitaryUserVisitLevel::query()
            ->where('user_id', $userId)
            ->where('visit_level', $visitLevel)
            ->first();
        if (empty($visit)) {
            $visit = ZPituitaryUserVisitLevel::query()->create([
                'user_id' => $data['user_id'],
                'hosp_id' => $data['hosp_id'],
                'dept_id' => $data['dept_id'],
                'visit_level' => $data['visit_level'],
                'visit_at' => $visitDate
            ]);
        }
        $retRecord = [
            'user_id' => $userId,
            'hosp_id' => $hospId,
            'dept_id' => $deptId,
            'type' => 0,
            'source' => 1,
            "visit_time" => $visitTime,
            "visit_at" => $visitDate,
            "doc_id" => $docId,
            "visit_id" => $visit->id,
            "created_at" => $visitTime,
            "updated_at" => $visitTime
        ];

        // 创建就诊
        $ret = ZPituitaryVisitRecords::insertOnDuplicateKey($retRecord);
        $recordId = $ret->id;

        return $this->success(["id" => $recordId]);
    }

}
